/**
 * 
 */
package fr.sinno.wms.batch.step;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import fr.sinno.wms.batch.dao.CommandExportRepository;
import fr.sinno.wms.batch.dao.CommandeRepository;
import fr.sinno.wms.batch.model.ExportedCommand;
import fr.sinno.wms.batch.model.LineCommand;
import fr.sinno.wms.batch.service.ExportService;

/**
 * @author aelguezzar
 *
 */
@Service("commandProcessorTasklet")
public class CommandProcessorTasklet implements Tasklet {

	private static final Logger LOG = Logger
			.getLogger(CommandProcessorTasklet.class);

//	@Autowired
//	private CommandExportRepository exportRepository;

	@Autowired
	private CommandeRepository commandRepository;

	private List<LineCommand> listSuppression = new ArrayList<LineCommand>();

	@Autowired
	private ExportService exportService;
	
	@Override
	@SuppressWarnings("unchecked")
	public RepeatStatus execute(StepContribution contribution,
			ChunkContext chunkContext) throws Exception {

		// RECUPERER LA LISTE DU CONTEXTE
		List<LineCommand> commandList = (List<LineCommand>) chunkContext
				.getStepContext().getStepExecution().getJobExecution()
				.getExecutionContext().get("commandList");

		List<LineCommand> listFilterCommand = new ArrayList<LineCommand>();
		String dateExport = new SimpleDateFormat("yyMMddHHmmss").format(new Date());
		
		Map<String, List<LineCommand>> mapCommand = new HashMap<String, List<LineCommand>>();
		for (LineCommand command : commandList) {
    		String designation = command.getDesignation();
			if (designation.contains(":")) {
				if (designation.length() > designation.indexOf(":")) {
					String codeLot = designation.substring(designation.indexOf(":") + 1);
					command.setCodeLot(codeLot.trim());
				}
			}
			if (mapCommand.containsKey(command.getCodeDocument())) {
				List<LineCommand> listTmp = mapCommand.get(command.getCodeDocument());
				listTmp.add(command);
			} else {
				List<LineCommand> newList = new ArrayList<LineCommand>();
				newList.add(command);
				mapCommand.put(command.getCodeDocument(), newList);
			}
		}
		
		List<ExportedCommand> allExported = exportService.getAllExported();
//		List<ExportedCommand> allExported = exportRepository.findAllExported();
		Map<String, List<ExportedCommand>> mapExported = new HashMap<String, List<ExportedCommand>>();

		for (ExportedCommand commandExp : allExported) {
			if (mapExported.containsKey(commandExp.getCodeDocument())) {
				List<ExportedCommand> listExpTmp = mapExported.get(commandExp.getCodeDocument());
				listExpTmp.add(commandExp);
			} else {
				List<ExportedCommand> newListExp = new ArrayList<ExportedCommand>();
				newListExp.add(commandExp);
				mapExported.put(commandExp.getCodeDocument(), newListExp);
			}
		}		

		Iterator<String> it = mapCommand.keySet().iterator();
	    while (it.hasNext()) {
	        String codeDoc = it.next();
	        if (null != codeDoc && codeDoc.length() > 4) {
		        List<LineCommand> listLinesTmp = mapCommand.get(codeDoc);
//		        if (codeDoc.equalsIgnoreCase("CC141748")) {
//		        	System.out.println("capte");
//		        }
		        if (mapExported.containsKey(codeDoc)) {
		        	
		        	// RECUPERER LA LISTE DE LA COMMANDE DEJA EXPORTEE
		        	List<ExportedCommand> listExportee = mapExported.get(codeDoc);
		        	if (notEquals(listLinesTmp, listExportee, allExported)) {
		        		// COMMANDE TRAITEE ET FERMEE PAR LE WMS, RENVOYER LA COMMANDE(RELIQUAT)
			        	for (LineCommand command : listLinesTmp) {
			        		
			        		if (null != command.getQuantite() && null != command.getQteLivree()) {
				        		Double qteCommandee = command.getQuantite() - command.getQteLivree();

								ExportedCommand exportedTmp = new ExportedCommand(command.getCodeDocument(), 
										command.getNumeroLigne(), command.getQuantite(), "", qteCommandee);
								int i = listExportee.indexOf(exportedTmp);
								if (i != -1) {
									listSuppression.add(command);
									ExportedCommand expTmp = listExportee.get(i);
									if (null == expTmp.getIsAlternatif() || !expTmp.getIsAlternatif().equalsIgnoreCase("true")) {
										listFilterCommand.add(command);

										if (allExported.contains(expTmp)) {
											int index = allExported.indexOf(expTmp);
											if (index != -1) {
												ExportedCommand newExp = allExported.get(index);
												newExp.setQteCommandee(qteCommandee);
												newExp.setDateExport(dateExport);
												newExp.setCodeLot(command.getCodeLot());
											}
										}
//						        		exportRepository.updateCommandExported(command, qteCommandee, dateExport);
									}
								} else {
									listFilterCommand.add(command);
									
									ExportedCommand newExp = new ExportedCommand();
									newExp.setCodeDocument(command.getCodeDocument());
									newExp.setNumeroLigne(command.getNumeroLigne());
									newExp.setQuantite(command.getQuantite());
									newExp.setDateExport(dateExport);
									newExp.setIsAlternatif(" ");
									newExp.setQteCommandee(qteCommandee);
									newExp.setCodeLot(command.getCodeLot());
									allExported.add(newExp);
//									exportRepository.insertCommandExported(command, qteCommandee, dateExport);
								}
				        		
			        		}
			        	}
		        	}
		        } else {
		        	// NOUVELLE COMMANDE POUR LE WMS, ENVOYER LA COMMANDE
		        	for (LineCommand command : listLinesTmp) {

// ACTIVER POUR L'INITIALISATION			
//		        		listSuppression.add(command);
		        		if (null != command.getQuantite() && null != command.getQteLivree()) {
			        		Double qteCommandee = command.getQuantite() - command.getQteLivree();
			        		listFilterCommand.add(command);

							ExportedCommand newExp = new ExportedCommand();
							newExp.setCodeDocument(command.getCodeDocument());
							newExp.setNumeroLigne(command.getNumeroLigne());
							newExp.setQuantite(command.getQuantite());
							newExp.setDateExport(dateExport);
							newExp.setQteCommandee(qteCommandee);
							newExp.setIsAlternatif(" ");
							newExp.setCodeLot(command.getCodeLot());
							allExported.add(newExp);
//			        		exportRepository.insertCommandExported(command, qteCommandee, dateExport);
		        		}
		        	}
		        }
	        }
	    }
		

		LOG.debug("NOMBRE DE COMMANDES APRES FILTRE : " + listFilterCommand.size());
		LOG.info("*********************************************************************************************************");

		chunkContext.getStepContext().getStepExecution().getJobExecution()
		.getExecutionContext().put("commandList", listFilterCommand);

		chunkContext.getStepContext().getStepExecution().getJobExecution()
		.getExecutionContext().put("removedList", listSuppression);

		chunkContext.getStepContext().getStepExecution().getJobExecution()
		.getExecutionContext().put("allExport", allExported);

		return RepeatStatus.FINISHED;
	}

	public boolean notEquals(List<LineCommand> listCommand, List<ExportedCommand> listExported, List<ExportedCommand> listAll) {
		if (listCommand.size() != listExported.size()) {
		    suppressionDeltaCommande(listCommand, listExported, listAll);
			return true;
		} else {
			for (LineCommand commande : listCommand) {
				if (null != commande.getQuantite() && null != commande.getQteLivree()) {
					Double qteCommandee = commande.getQuantite() - commande.getQteLivree();
					ExportedCommand exportedTmp = new ExportedCommand(commande.getCodeDocument(), 
							commande.getNumeroLigne(), commande.getQuantite(), "", qteCommandee);
					String codeLotCommande = commande.getCodeLot();
					if (null == codeLotCommande) {
						codeLotCommande = " ";
					}
					if (listExported.contains(exportedTmp)) {
						int i = listExported.indexOf(exportedTmp);
						if (i != -1 && null != listExported.get(i).getQteCommandee() 
								&& null != qteCommandee
								&& ( listExported.get(i).getQteCommandee().intValue() != qteCommandee.intValue() 
										|| !listExported.get(i).getCodeLot().equalsIgnoreCase(codeLotCommande) ) ) {
						    suppressionDeltaCommande(listCommand, listExported, listAll);
							return true;
						}
					} else {
					    suppressionDeltaCommande(listCommand, listExported, listAll);
					    return true;
					}
				}
			}
		}
		return false;
	}

	public void suppressionDeltaCommande (List<LineCommand> listCommand, List<ExportedCommand> listExported, List<ExportedCommand> listAll) {
		// SUPPRESSION DE LA LIGNE DE COMMANDE SOLDEE
		for (ExportedCommand commandeExp : listExported) {
			String codeDocumentTmp = commandeExp.getCodeDocument();
			Double numeroLigneTmp = commandeExp.getNumeroLigne();
			LineCommand commandTmp = new LineCommand();
			commandTmp.setCodeDocument(codeDocumentTmp);
			commandTmp.setNumeroLigne(numeroLigneTmp);
			if (!listCommand.contains(commandTmp)) {
				if (null != numeroLigneTmp) {
					// DETECTER UNE SUPRESSION DE LIGNE
					LineCommand commandExist = commandRepository.findUniqueCommandById(codeDocumentTmp, numeroLigneTmp.intValue());
					if (null == commandExist) {
						//ENVOYER FICHIER SUPPRESSION
						listSuppression.add(commandTmp);
					}
					// SUPPRIMER LA LIGNE SOLDEE OU SUPPRIMEE
					if (listAll.contains(commandeExp)) {
						int index = listAll.indexOf(commandeExp);
						if (index != -1) {
							ExportedCommand newExp = listAll.get(index);
							listAll.remove(newExp);
						}
					}
//					exportRepository.deleteCommandExported(codeDocumentTmp, numeroLigneTmp.intValue());
				}
			}
		}
	}

//	public CommandExportRepository getExportRepository() {
//		return exportRepository;
//	}
//
//	public void setExportRepository(CommandExportRepository exportRepository) {
//		this.exportRepository = exportRepository;
//	}

	public CommandeRepository getCommandRepository() {
		return commandRepository;
	}

	public void setCommandRepository(CommandeRepository commandRepository) {
		this.commandRepository = commandRepository;
	}

}